home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
BORL_TIP
/
TI100
/
TI114.ASC
< prev
next >
Wrap
Text File
|
1991-09-11
|
12KB
|
463 lines
PRODUCT : TURBO PASCAL NUMBER : 114
VERSION : ALL
OS : MS-DOS
DATE : December 4, 1986 PAGE : 1/7
TITLE : MS-DOS INTERRUPT 24 TRAP ROUTINE
The following example routines are public domain programs that
have been uploaded to our Forum on CompuServe. As a courtesy to
our users that do not have immediate access to CompuServe,
Technical Support distributes these routines free of charge.
However, because these routines are public domain programs, not
developed by Borland International, we are unable to provide any
technical support or assistance using these routines. If you need
assistance using these routines, or are experiencing
difficulties, we recommend that you log onto CompuServe and
request assistance from the Forum members that developed these
routines.
Thanks to Marshall Brain for the original code for this routine.
These routines provide a method for Turbo Pascal programs to trap
MS-DOS interrupt 24. INT 24 is called by DOS when a "critical
error" occurs, and it normally prints the familiar "Abort, Retry,
Ignore?" message.
With the INT 24 handler installed, errors of this type will be
passed on to Turbo Pascal as an error. If I/O checking is on,
this will cause a program crash. If I/O checking is off, IOResult
will return an error code. The global variable INT24Err will be
true if an INT 24 error has occurred. The variable INT24ErrorCode
will contain the INT 24 error code as given by DOS. These errors
can be found in the DOS Technical Reference Manual. They
correspond to the error codes returned by the function
INT24Result, with an offset of 256. INT24Result is used like
IOResult, and calls IOResult. It then checks INT24Err, and if it
is true, returns INT24ErrorCode+256, instead.
In most cases, INT24Result should be used, because INT24Err must
be set back to false, and DOS sometimes restores its normal INT
24 handler after an error.
-------------------------------------------------------------------
**Note: Turbo's normal IOResult codes (and Turbo Access error
codes) for MS-DOS DO NOT correspond to I/O error numbers given in
Appendix I of the Turbo Pascal manual, or error codes given in
the I/O error nn, PC=aaaa/Program aborted message. Here is a
table of correspondence (all numbers are in hexadecimal and
(decimal)):
PRODUCT : TURBO PASCAL NUMBER : 114
VERSION : ALL
OS : MS-DOS
DATE : December 4, 1986 PAGE : 2/7
TITLE : MS-DOS INTERRUPT 24 TRAP ROUTINE
IOResult Turbo error
---------- -----------------------------------------------
00 (0) 00 (0) none
01 (1) 90 (144) record length mismatch
02 (2) 01 (1) file does not exist
03 (3) F1 (241) directory is full
04 (4) FF (255) file disappeared
05 (5) 02 (2) file not open for input
06 (6) 03 (3) file not open for output
07 (7) 99 (153) unexpected end of file
08 (8) F0 (240) disk write error
09 (9) 10 (16) error in numeric format
0A (10) 99 (153) unexpected end of file
0B (11) F2 (242) file size overflow
0C (12) 99 (153) unexpected end of file
0D (13) F0 (240) disk write error
0E (14) 91 (145) seek beyond end of file
0F (15) 04 (4) file not open
10 (16) 20 (32) operation not allowed on a logical device
11 (17) 21 (33) not allowed in direct mode
12 (18) 22 (34) assign to standard files is not allowed
90 (144) 90 (144) record length mismatch
program CriticalError;
Const INT24Err : Boolean=False;
INT24ErrCode : Byte=0;
OldINT24 : Array [1..2] Of Integer=(0,0);
Var RegisterSet : Record Case Integer Of
1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte);
End;
Procedure INT24;
Const FCBFuncs: Array [1..6] Of Byte=(14,15,21,22,27,28);
Begin
{ To understand this routine, you will need to read the description of
Interrupt 24h in the DOS manual. It also helps to examine and trace the
generated code under DEBUG. }
Inline($0E/$0E/$1F/$07/$C6/$06/ INT24Err /$01/$89/$EC/$83/$C4/$08/
$89/$F8/$A2/ INT24ErrCode /$58/$B9/$06/$00/$BF/ FCBFuncs /$F2/
PRODUCT : TURBO PASCAL NUMBER : 114
VERSION : ALL
OS : MS-DOS
DATE : December 4, 1986 PAGE : 3/7
TITLE : MS-DOS INTERRUPT 24 TRAP ROUTINE
$AE/$75/$04/$B0/$01/$EB/$08/$3C/$39/$B0/$FF/$72/$02/$B0/$83/
$5B/$59/$5A/$5E/$5F/$89/$E5/$80/$4E/$0A/$01/$5D/$1F/$07/$CF);
{ Turbo: PUSH BP (Save caller's stack frame
MOV BP,SP Set up this procedure's stack frame
PUSH BP ?)
Inline: PUSH CS
PUSH CS
POP DS Set DS and ES temporarily to CS
POP ES
MOV BYTE [INT24Err],1 Set INT24Err to True (CS:)
MOV SP,BP Get correct SP; ADD: Discard saved
ADD SP,8 BP, INT 24h return address & flags
MOV AX,DI Get INT 24h error code
MOV [INT24ErrCode],AL Save it in INT24ErrCode
POP AX Get initial DOS call number
MOV CX,6 Search for it in FCBFuncs: is this one
MOV DI,Offset FCBFuncs of the FCB functions that requires an
REPNZ SCASB error code of 01 in AL?
JNZ .1
MOV AL,1 Yes: set it
JMP .2
.1 CMP AL,39h No: is it an FCB function that requires
MOV AL,0FFh AL=FFh (function <39h)? Yes: set it.
JB .2
MOV AL,83h No: handle call, return error 83h, call
failed via INT 24h.
The error code (1, FFh or 83h) is
returned to the Turbo runtime routine
that called DOS, making it look like
a simple DOS error. Turbo handles
the I/O error.
.2 POP BX Pop the rest of the registers saved by
POP CX the initial INT 21h.
POP DX
POP SI
POP DI
MOV BP,SP
OR Byte Ptr [BP+0Ah],1 Set the carry flag in the saved Flags reg.
POP BP
POP DS
POP ES
IRET Return to next instruction: all regs.
PRODUCT : TURBO PASCAL NUMBER : 114
VERSION : ALL
OS : MS-DOS
DATE : December 4, 1986 PAGE : 4/7
TITLE : MS-DOS INTERRUPT 24 TRAP ROUTINE
restored, AL=error code, carry set. }
End;
Procedure INT24On; {Enable INT 24 trapping}
Begin
INT24Err:=False;
With RegisterSet Do
Begin
AX:=$3524;
MsDos(RegisterSet);
If (OldINT24[1] Or OldINT24[2]) = 0 Then
Begin
OldINT24[1]:=ES;
OldINT24[2]:=BX;
End;
DS:=CSeg;
DX:=Ofs(INT24);
AX:=$2524;
MsDos(RegisterSet);
End;
End;
Procedure INT24Off; {Disable INT 24 trapping. Should be done at the
end of the program, if you plan to be running
the program from within the Turbo compiler.}
Begin
INT24Err:=False;
If OldINT24[1]<>0 Then
With RegisterSet Do
Begin
DS:=OldINT24[1];
DX:=OldINT24[2];
AX:=$2524;
MsDos(RegisterSet);
End;
OldINT24[1]:=0;
OldINT24[2]:=0;
End;
Function INT24Result: Integer;
PRODUCT : TURBO PASCAL NUMBER : 114
VERSION : ALL
OS : MS-DOS
DATE : December 4, 1986 PAGE : 5/7
TITLE : MS-DOS INTERRUPT 24 TRAP ROUTINE
Var I : Integer;
Begin
I:=IOResult;
If INT24Err Then
Begin
I:=I+256*(INT24ErrCode+1);
INT24On;
End;
INT24Result:=I;
End;
{ INT24Result returns all the regular Turbo IOResult codes if no
critical error has occurred. If a critical error, then the
following values are added to the error code from Turbo (each
is 256 times the INT24ErrorCode value returned by DOS):
256: Attempt to write on write protected disk
512: Unknown unit [internal dos error]
768: Drive not ready [drive door open or bad drive]
1024: Unknown command [internal dos error]
1280: Data error (CRC) [bad sector or drive]
1536: Bad request structure length [internal dos error]
1792: Seek error [bad disk or drive]
2048: Unknown media type [bad disk or drive]
2304: Sector not found [bad disk or drive]
2560: Printer out of paper [anything that the printer
might signal]
2816: Write fault [character device not ready]
3072 Read fault [character device not ready]
3328: General failure [several meanings]
If you need the IOResult part, use
I:=INT24Result and 255; [masks out the INT 24 code]
For the INT 24 code, use
I:=INT24Result Shr8; [same as Div 256, except faster]
INT24Result clears both error codes, so you must assign it to
a variable if you want to extract both codes:
J:=INT24Result;
Writeln('Turbo IOResult = ',J And 255);
PRODUCT : TURBO PASCAL NUMBER : 114
VERSION : ALL
OS : MS-DOS
DATE : December 4, 1986 PAGE : 6/7
TITLE : MS-DOS INTERRUPT 24 TRAP ROUTINE
Writeln('DOS INT 24 code = ',J Shr 8); }
{ Main program }
{ Run this with printer off (or no printer), and nothing in drive A }
Var F : File;
I : Integer;
Procedure PrinterTest;
Begin
WriteLn(LST,'test');
I:=INT24Result;
If I<>0 Then
WriteLn('Printer error: ',I)
Else
WriteLn('Printer OK');
End;
Procedure FileTest;
Begin
Assign(F,'A:FILE');
{$I-}
Reset(F);
{$I+}
I:=INT24Result;
If I<>0 Then
WriteLn('Open failure on A:FILE : INT24Result=',I)
Else
begin
WriteLn('A:FILE exists');
Close(F);
end;
End;
Begin
INT24On;
PrinterTest;
FileTest;
PrinterTest;
INT24Off;
FileTest;
PRODUCT : TURBO PASCAL NUMBER : 114
VERSION : ALL
OS : MS-DOS
DATE : December 4, 1986 PAGE : 7/7
TITLE : MS-DOS INTERRUPT 24 TRAP ROUTINE
PrinterTest;
End.